package com.starblink.search.result.ui.widget

import android.content.Context
import android.graphics.Color
import android.text.TextUtils
import android.util.ArrayMap
import android.util.AttributeSet
import android.view.Gravity
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.DecelerateInterpolator
import android.view.animation.TranslateAnimation
import android.widget.FrameLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.LinearLayoutManager
import com.starblink.android.basic.adapter.BaseVH
import com.starblink.android.basic.adapter.MutableAdapter
import com.starblink.android.basic.brv.DefaultDecoration
import com.starblink.android.basic.ext.color
import com.starblink.android.basic.ext.enableCorner
import com.starblink.android.basic.ext.gone
import com.starblink.android.basic.ext.inflater
import com.starblink.android.basic.ext.isGone
import com.starblink.android.basic.ext.isVisible
import com.starblink.android.basic.ext.visible
import com.starblink.android.basic.extension.dp2px
import com.starblink.android.basic.extension.lazyOnNone
import com.starblink.android.basic.util.FontUtil
import com.starblink.basic.style.R
import com.starblink.search.databinding.PopGoodsFrontFilterBinding
import com.starblink.search.result.repository.model.IFrontProperty
import com.starblink.search.result.repository.model.SelectableBrand
import com.starblink.search.result.repository.model.SelectableBrandWrap
import com.starblink.search.result.repository.model.SelectableProperty
import com.starblink.search.result.repository.model.SelectablePropertyWrap

class GoodsFrontFilterPopView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    themeId: Int = 0,
) :
    FrameLayout(context, attrs, themeId) {

    var onSelect: (() -> Unit)? = null

    var onDismiss: (() -> Unit)? = null

    var data: IFrontProperty? = null

    private val binding =
        PopGoodsFrontFilterBinding.inflate(this.inflater, this)

    private val list = arrayListOf<Any>()

    private val propertyCache = ArrayMap<Int, SelectableProperty>()

    private val brandCache = ArrayMap<Int, SelectableBrand>()

    private val adapter by lazyOnNone {
        MutableAdapter(list).apply {
            addVhDelegate {
                PropertyCell(it, propertyCache) { position, model ->

                }.apply {

                }
            }
            addVhDelegate {
                BrandCell(it, brandCache) { position, model ->

                }
            }
        }
    }

    private val showAnim = onCreateShowAnimation()

    private val dismissAnim = onCreateDismissAnimation().apply {
        setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationStart(animation: Animation?) {

            }

            override fun onAnimationEnd(animation: Animation?) {
                gone()
            }

            override fun onAnimationRepeat(animation: Animation?) {

            }
        })
    }

    fun setupData(data: IFrontProperty) {
        this.data = data
        list.clear()
        propertyCache.clear()
        brandCache.clear()

        if (data is SelectablePropertyWrap) {
            list.addAll(data.properties)
            data.properties.forEachIndexed { index, selectableProperty ->
                if (selectableProperty.selected) {
                    propertyCache[index] = selectableProperty
                }
            }
        } else if (data is SelectableBrandWrap) {
            list.addAll(data.brands)
            data.brands.forEachIndexed { index, selectableProperty ->
                if (selectableProperty.selected) {
                    brandCache[index] = selectableProperty
                }
            }
        }
        binding.recycler.updateLayoutParams<ViewGroup.LayoutParams> {
            height = if (list.size > 5) {
                260.dp2px()
            } else {
                (36 * list.size + 16).dp2px()
            }
        }
        adapter.refreshAll()
    }

    init {
        setBackgroundColor(Color.parseColor("#AD0F172A"))

        binding.content.enableCorner(32.dp2px(), "bottom")
//        binding.recycler.enableCorner(16.dp2px())
        binding.recycler.isNestedScrollingEnabled = false
        binding.recycler.layoutManager = LinearLayoutManager(context)
        binding.recycler.adapter = adapter
        binding.recycler.addItemDecoration(DefaultDecoration(context).apply {
            startVisible = true
            endVisible = true
            this.setDivider(16.dp2px())
        })

        binding.btnSure.setOnClickListener {
            list.forEachIndexed { index, selectableProperty ->
                if (selectableProperty is SelectableProperty) {
                    selectableProperty.selected = propertyCache[index] == selectableProperty
                } else if (selectableProperty is SelectableBrand) {
                    selectableProperty.selected = brandCache[index] == selectableProperty
                }

            }
            onSelect?.invoke()
            dismiss()
        }
        binding.btnCancel.setOnClickListener {
            dismiss()
        }
        binding.root.setOnClickListener {
            dismiss()
        }
        binding.content.setOnClickListener {

        }
    }

    fun show() {
        if (isVisible) return
        visible()
        binding.content.startAnimation(showAnim)
    }

    fun dismiss() {
        if (isGone) return

        binding.content.startAnimation(dismissAnim)
    }

    fun isShowing(): Boolean {
        return isVisible
    }

    override fun onDetachedFromWindow() {
        showAnim.cancel()
        dismissAnim.cancel()
        super.onDetachedFromWindow()
    }

    override fun setVisibility(visibility: Int) {
        super.setVisibility(visibility)
        if (visibility == GONE) {
            onDismiss?.invoke()
        }
    }


    private fun onCreateShowAnimation(): Animation = TranslateAnimation(
        Animation.RELATIVE_TO_PARENT,
        0f,
        Animation.RELATIVE_TO_PARENT,
        0f,
        Animation.RELATIVE_TO_PARENT,
        -1f,
        Animation.RELATIVE_TO_PARENT,
        0f
    ).apply {
        interpolator = DecelerateInterpolator()
        duration = 300
    }

    private fun onCreateDismissAnimation(): Animation = TranslateAnimation(
        Animation.RELATIVE_TO_PARENT,
        0f,
        Animation.RELATIVE_TO_PARENT,
        0f,
        Animation.RELATIVE_TO_PARENT,
        0f,
        Animation.RELATIVE_TO_PARENT,
        -1f
    ).apply {
        interpolator = DecelerateInterpolator()
        duration = 300
    }

    fun getContentView() = binding.content


    companion object {

        private const val TAG = "GoodsFrontFilterPop"

    }
}


private class PropertyCell(
    parent: ViewGroup,
    val propertyCache: ArrayMap<Int, SelectableProperty>,
    val onSelect: ((position: Int, model: SelectableProperty) -> Unit)? = null
) :
    BaseVH<SelectableProperty>(TextView(parent.context).apply {
        layoutParams =
            ViewGroup.MarginLayoutParams(
                ViewGroup.MarginLayoutParams.MATCH_PARENT,
                ViewGroup.MarginLayoutParams.WRAP_CONTENT
            )
    }) {

    private val text = itemView as TextView

    val colorNormal = color(R.color.gu_text_primary)
    val colorSelect = color(R.color.gu_text_brand600)

    val selectDrawable =
        ContextCompat.getDrawable(itemView.context, R.mipmap.ic_goods_filter_confirm)

    init {
        FontUtil.setSansRegula(text)
        text.setPadding(16.dp2px(), 0, 16.dp2px(), 0)
        text.gravity = Gravity.CENTER_VERTICAL
        text.setTextColor(colorNormal)
        text.textSize = 14f
        text.ellipsize = TextUtils.TruncateAt.END
        text.compoundDrawablePadding = 8.dp2px()
        text.maxLines = 1
    }

    override fun onBind(model: SelectableProperty, position: Int) {
        text.text = model.text
        val select = propertyCache[position] == model
        if (select) {
            text.setTextColor(colorSelect)
            text.setCompoundDrawablesWithIntrinsicBounds(null, null, selectDrawable, null)
        } else {
            text.setTextColor(colorNormal)
            text.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
        }
        text.setOnClickListener {
            if (select) {
                propertyCache.remove(position)
            } else {
                propertyCache[position] = model
            }
            //model.selected = !model.selected
            onBind(model, position)
            onSelect?.invoke(position, model)
        }
    }

}

private class BrandCell(
    parent: ViewGroup,
    val propertyCache: ArrayMap<Int, SelectableBrand>,
    val onSelect: ((position: Int, model: SelectableBrand) -> Unit)? = null
) :
    BaseVH<SelectableBrand>(TextView(parent.context).apply {
        layoutParams =
            ViewGroup.MarginLayoutParams(
                ViewGroup.MarginLayoutParams.MATCH_PARENT,
                ViewGroup.MarginLayoutParams.WRAP_CONTENT
            )
    }) {

    private val text = itemView as TextView

    val colorNormal = color(R.color.sk_gray500)
    val colorSelect = color(R.color.sk_red600)

    val selectDrawable =
        ContextCompat.getDrawable(itemView.context, R.mipmap.ic_goods_filter_confirm)

    init {
        FontUtil.setSansRegula(text)
        text.setPadding(16.dp2px(), 0, 16.dp2px(), 0)
        text.gravity = Gravity.CENTER_VERTICAL
        text.setTextColor(colorNormal)
        text.textSize = 16f
        text.ellipsize = TextUtils.TruncateAt.END
        text.compoundDrawablePadding = 8.dp2px()
        text.maxLines = 1
    }

    override fun onBind(model: SelectableBrand, position: Int) {
        text.text = model.source.name
        val select = propertyCache[position] == model
        if (select) {
            text.setTextColor(colorSelect)
            text.setCompoundDrawablesWithIntrinsicBounds(null, null, selectDrawable, null)
        } else {
            text.setTextColor(colorNormal)
            text.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
        }
        text.setOnClickListener {
            if (select) {
                propertyCache.remove(position)
            } else {
                propertyCache[position] = model
            }
            //model.selected = !model.selected
            onBind(model, position)
            onSelect?.invoke(position, model)
        }
    }

}